package com.t21;

import java.io.InputStream;
import java.util.concurrent.*;

import static net.mindview.util.Print.print;

/**
 * Created by xuyiwei on 2018/9/23.
 */
class SleepBlocked implements Runnable{
    @Override
    public void run() {
        try{
            TimeUnit.SECONDS.sleep(100);
        }catch (Exception e){
            print("InterruptedException");
        }
        print("Exiting SleepBlocked.run()");
    }
}
class IOBlocked implements Runnable{
    private InputStream in;
    public IOBlocked(InputStream in) {
        this.in = in;
    }
    public void run(){
        try{
            print("Waiting for read()");
            in.read();
        }catch (Exception e){
            if(Thread.currentThread().isInterrupted()){
                print("Interrupted from blocked I/O");
            }else{
                throw new RuntimeException(e);
            }
        }
    }
}
class SynchronizedBlocked implements Runnable{
    public synchronized void f(){
        while (true){
            Thread.yield();
        }
    }

    public SynchronizedBlocked() {
        new Thread(){
            public void run(){
                f();
            }
        }.start();
    }

    @Override
    public void run() {
        print("Trying to call f()");
        f();
        print("Exiting SynchronizedBlocked.run()");
    }
}
public class Interrupting {
    private static ExecutorService exec =
            Executors.newCachedThreadPool();
    static void test(Runnable r) throws InterruptedException{
        Future<?> f = exec.submit(r);
        TimeUnit.MILLISECONDS.sleep(100);
        print("Interrupting " + r.getClass().getName());
        f.cancel(true); // Interrupts if running
        print("Interrupt sent to " + r.getClass().getName());
    }
    public static void main(String[] args) throws Exception {
        test(new SleepBlocked());
        test(new IOBlocked(System.in));
        test(new SynchronizedBlocked());
        TimeUnit.SECONDS.sleep(3);
        print("Aborting with System.exit(0)");
        System.exit(0); // ... since last 2 interrupts failed
    }
    /**
     * Interrupting com.t21.SleepBlocked
     Interrupt sent to com.t21.SleepBlocked
     InterruptedException
     Exiting SleepBlocked.run()
     Waiting for read()
     Interrupting com.t21.IOBlocked
     Interrupt sent to com.t21.IOBlocked
     Trying to call f()
     Interrupting com.t21.SynchronizedBlocked
     Interrupt sent to com.t21.SynchronizedBlocked
     Aborting with System.exit(0)
     */
}
